/**
 * Copyright (c) 2023 murenchao
 * taomu is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *       http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package cool.taomu.toolkit

import com.google.common.util.concurrent.ListeningExecutorService
import com.google.inject.Injector
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.ConcurrentSkipListMap
import java.util.function.Supplier
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend.lib.annotations.ToString
import org.slf4j.LoggerFactory
import com.google.inject.Key
import java.lang.annotation.Annotation
import com.google.inject.name.Names

@Accessors
@ToString
class Context {
    val static LOG = LoggerFactory.getLogger(Context);
    Supplier<Injector> injectorSupplier;

    val static ConcurrentMap<String, Object> c = new ConcurrentSkipListMap<String, Object>();

    def <T> void set(String key, T value) {
        c.put(key, value);
    }

    def <T> T get(String key) {
        return c.get(key) as T
    }

    def setSupplierInjector(Injector injector) {
        LOG.debug("设置injector:{}", injector.toString);
        this.injectorSupplier = new Supplier<Injector>() {
            override get() {
                injector
            }
        }
    }

    def getSupplierInjector() {
        this.injectorSupplier
    }

    def executor() {
        this.injectorSupplier.get().getInstance(ListeningExecutorService)
    }

    def getInstance(Class<?> zlass) {
        this.injectorSupplier.get().getInstance(zlass)
    }

    def <T> getInstance(Key<T> key) {
        this.injectorSupplier.get().getInstance(key)
    }

    def boolean isExistingBinding(Class<?> zlass, String ann) {
        this.injectorSupplier.get.getExistingBinding(Key.get(zlass, Names.named(ann))) !== null
    }

}
